/*
 *  This file was originally created by Ireneusz Grala in August 2010
 *  e-mail: ireneusz.grala@wp.pl
 *  
 */
using System;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.IO;

using IRQ.GPS.Distance;
using IRQ.BaseFunctions.Drawing;

using Microsoft.WindowsMobile.Samples.Location;
//using Microsoft.WindowsMobile.Status;

using SimpleGPSApp.Base;
using SimpleGPSApp.Forms;
using SimpleGPSApp.pl.portalkierowcy;
using IRQ.BaseFunctions;
using Microsoft.WindowsMobile.Status;

namespace SimpleGPSApp
{
    public partial class GPSViewer : Form
    {
        private Gps gps = new Gps();
        private EventHandler updateEvent;
        private GpsPosition position = null;
        private GpsDeviceState deviceState = null;
        private SystemState batteryLevel = new SystemState(SystemProperty.PowerBatteryStrength);
        private SystemState batteryState = new SystemState(SystemProperty.PowerBatteryState);
        server server = new server();
        System.Threading.Timer timer;
        System.Threading.TimerCallback timerCallback;
        public delegate void UpdateStatusBarDelegate(string text);
        private static object locker = new object();

        public GPSViewer()
        {
            InitializeComponent();
            updateEvent = new EventHandler(Update);
            gps.LocationChanged += new LocationChangedEventHandler(gps_LocationChanged);
            gps.DeviceStateChanged += new DeviceStateChangedEventHandler(gps_DeviceStateChanged);
            batteryLevel.Changed += new ChangeEventHandler(batteryLevel_Changed);
            batteryState.Changed += new ChangeEventHandler(batteryState_Changed);
            ManageGPS();
            timerCallback = new System.Threading.TimerCallback(TimerMethod);
            timer = new System.Threading.Timer(timerCallback, null, 5000, Root.ApplicationSettings.PositionLogFrequency);
            this.unitValueControl_time.Value = DateTime.Now.ToString();
            SetBottomImages();
        }

        #region System properties
        void batteryState_Changed(object sender, ChangeEventArgs args)
        {
            SetBatteryState();
        }

        void batteryLevel_Changed(object sender, ChangeEventArgs args)
        {
            SetBatteryState();
        }
        #endregion

        private void ManageGPS()
        {
            if (!gps.Opened)
            {
                gps.Open();
                return;
            }

            if (gps.Opened)
            {
                gps.Close();
            }
        }

        void gps_DeviceStateChanged(object sender, DeviceStateChangedEventArgs args)
        {
            deviceState = args.DeviceState;
           
            Invoke(updateEvent);
        }

        void gps_LocationChanged(object sender, LocationChangedEventArgs args)
        {
            position = args.Position;
            Invoke(updateEvent);
        }

        private void Update(object sender, EventArgs e)
        {
            if (deviceState != null)
            {
                switch (deviceState.DeviceState)
                {
                    case GpsServiceState.On:
                        this.pictureBox_deviceState.Image = Properties.Resources.gps;
                        break;
                    default:
                        this.pictureBox_deviceState.Image = Properties.Resources.gps_off;
                        break;
                }
            }

            if (gps.Opened)
            {
                if (position != null)
                {
                    if (position.TimeValid)
                    {
                        this.unitValueControl_time.Value = position.Time.ToString();
                        this.unitValueControl_time.Refresh();
                    }
                    this.gpsInformation1.Position = this.position;
                    this.satellitesSignalPosition1.Position = this.position;
                }
            }
        }

        #region Form events
        private void GPSViewer_Closed(object sender, EventArgs e)
        {
            ManageGPS();
        }
        private void GPSViewer_Load(object sender, EventArgs e)
        {
            SetBatteryState();
        }
        #endregion

        private void SyncSystemClockWithGps()
        {
            if (this.position != null && position.TimeValid)
            {
                DateTime timeToSet = position.Time.ToUniversalTime();

                SystemVariables.SYSTEMTIME systemTime = new SystemVariables.SYSTEMTIME();
                systemTime.wYear = (ushort)DateTime.Now.Year;
                systemTime.wMonth = (ushort)DateTime.Now.Month;
                systemTime.wDay = (ushort)DateTime.Now.Day;
                systemTime.wHour = (ushort)timeToSet.ToLocalTime().Hour;
                systemTime.wMinute = (ushort)timeToSet.Minute;
                systemTime.wSecond = (ushort)timeToSet.Second;

                SystemVariables.SetSystemTime(ref systemTime);
            }
        }

        private void SetBatteryState()
        {
            try
            {
                bool isCharging = (SystemState.PowerBatteryState == BatteryState.Charging) ? true : false;

                BatteryStateImage(isCharging);
            }
            catch { }
        }

        private void BatteryStateImage(bool _isCharging)
        {
            switch (SystemState.PowerBatteryStrength)
            {
                case BatteryLevel.VeryHigh:
                    pictureBox_battery.Image = (_isCharging) ?
                        Properties.Resources.battery_level_very_high_charging28x15 : Properties.Resources.battery_level_very_high28x15;
                    break;
                case BatteryLevel.High:
                    pictureBox_battery.Image = (_isCharging) ?
                        Properties.Resources.battery_level_high_charging28x15 : Properties.Resources.battery_level_high28x15;
                    break;
                case BatteryLevel.Medium:
                    pictureBox_battery.Image = (_isCharging) ?
                        Properties.Resources.battery_level_medium_charging28x15 : Properties.Resources.battery_level_medium28x15;
                    break;
                case BatteryLevel.Low:
                    pictureBox_battery.Image = (_isCharging) ?
                        Properties.Resources.battery_level_low_charging28x15 : Properties.Resources.battery_level_low28x15;
                    break;
                case BatteryLevel.VeryLow:
                    pictureBox_battery.Image = (_isCharging) ?
                        Properties.Resources.battery_level_very_low_charging28x15 : Properties.Resources.battery_level_very_low28x15;
                    break;
            }
        }

        private void SetBottomImages()
        {
            this.pictureBox_close.Image = Properties.Resources.application_exit_3;
            this.pictureBox_satellites.Image = Properties.Resources.network_satellite_off;
            this.pictureBox_settings.Image = Properties.Resources.system_settings_2;
            this.pictureBox_clockSync.Image = Properties.Resources.clock_2;

            SetLoggingTypeImage();
        }

        private void SetLoggingTypeImage()
        {
            switch (Root.ApplicationSettings.LogingType)
            {
                case LogType.File:
                    this.pictureBox_loggingType.Image = Properties.Resources.document_save_4;
                    break;
                case LogType.FileAndServer:
                case LogType.Server:
                    this.pictureBox_loggingType.Image = Properties.Resources.document_send;
                    break;
                default:
                    this.pictureBox_loggingType.Image = Properties.Resources.document_save_4_off;
                    break;
            }
        }

        private void TimerMethod(object state)
        {
            if (Root.ApplicationSettings != null)
            {
                if (position != null)
                {
                    try
                    {
                        Logger.LogPosition(position, server);
                        this.pictureBox_savingStatus.Invoke(new Action(() => { this.pictureBox_savingStatus.Image = null; }));
                    }
                    catch (Exception e)
                    {
                        ErrorLog.WriteError(Root.ErrorLogFileName, "LogPosition: " + e.ToString());
                        this.pictureBox_savingStatus.Invoke(new Action(() => { this.pictureBox_savingStatus.Image = Properties.Resources.network_error; }));
                    }
                    lock (locker)
                    {
                        ApplicationHelper.SaveXmlFile<Statistics>(Root.Statistics, Root.StatisticsFile);
                    }
                }
            }
        }
       
        private void pictureBox_close_Click(object sender, EventArgs e)
        {
            server.Abort();
            timer.Dispose();
            this.Close();
        }

        private void pictureBox_satellites_Click(object sender, EventArgs e)
        {
            if (!this.satellitesSignalPosition1.Visible)
            {
                this.satellitesSignalPosition1.Visible = true;
                this.gpsInformation1.Visible = false;
                this.satellitesSignalPosition1.BringToFront();

                this.pictureBox_satellites.Image = Properties.Resources.network_satellite;
            }
            else
            {
                this.satellitesSignalPosition1.Visible = false;
                this.gpsInformation1.Visible = true;
                this.gpsInformation1.BringToFront();
                this.pictureBox_satellites.Image = Properties.Resources.network_satellite_off;
            }
        }

        private void pictureBox_settings_Click(object sender, EventArgs e)
        {
            using (FormSettings settings = new FormSettings())
            {
                settings.ShowDialog();
                SetLoggingTypeImage();
            }
        }

        private void pictureBox_clockSync_Click(object sender, EventArgs e)
        {
            this.SyncSystemClockWithGps();
        }
    }
}